Imports System.Data.Objects


Public MustInherit Class BaseEntityRepository(Of TType As {TSet, Class}, TSet As Class)
    Implements IEntityRepository(Of TType)

    Private _context As AsindoContext

    Public Sub New(ByVal context As AsindoContext)
        _context = context
    End Sub

    Protected MustOverride ReadOnly Property ObjectSets As ICollection(Of ObjectSet(Of TSet))
    Protected MustOverride ReadOnly Property MainObjectSet As ObjectSet(Of TSet)

    Public MustOverride Function GetID(ByVal obj As TType) As Integer

    Protected ReadOnly Property Context As AsindoContext
        Get
            Return _context
        End Get
    End Property

    Function Create() As TType Implements IEntityRepository(Of TType).Create
        Return Context.CreateObject(Of TType)()
    End Function


    Public Function GetByID(ByVal id As Integer?, ParamArray includePaths() As String) As TType Implements IEntityRepository(Of TType).GetById
        If id.HasValue Then
            Dim q = GetByIdQuery(MainObjectSet.OfType(Of TType), id.Value)
            If includePaths Is Nothing Then
                Return GetByIdQuery(MainObjectSet.OfType(Of TType), id.Value).SingleOrDefault()
            Else
                For Each includePath In includePaths
                    q = q.Include(includePath)
                Next
            End If
            Return q.SingleOrDefault()
        Else
            Return Nothing
        End If
    End Function

    Protected MustOverride Function GetByIdQuery(ByVal qbase As IQueryable(Of TType), ByVal id As Integer) As IQueryable(Of TType)

    Public Sub Add(ByVal entity As TType, Optional ByVal save As Boolean = True) Implements IEntityRepository(Of TType).Add
        MainObjectSet.AddObject(entity)
        If save Then Context.SaveChanges()
    End Sub

    Public Sub DeleteById(ByVal id As Integer, Optional ByVal save As Boolean = True) Implements IEntityRepository(Of TType).DeleteById
        MainObjectSet.DeleteObject(GetByID(id))
        If save Then Context.SaveChanges()
    End Sub

    Public Sub Delete(ByVal entity As TType, Optional ByVal save As Boolean = True) Implements IEntityRepository(Of TType).Delete
        MainObjectSet.DeleteObject(entity)
        If save Then Context.SaveChanges()
    End Sub

    Public Function All() As IQueryable(Of TType) Implements IEntityRepository(Of TType).All
        Return MainObjectSet.OfType(Of TType)()
    End Function

    Public MustOverride Function CreateDetached() As TType Implements IEntityRepository(Of TType).CreateDetached
End Class

Public MustInherit Class BaseEntityRepository(Of TType As {Class})
    Inherits BaseEntityRepository(Of TType, TType)

    Public Sub New(ByVal context As AsindoContext)
        MyBase.New(context)
    End Sub

End Class